package com.csweimei.rentmanagementtreasure.http;


import android.util.Base64;
import android.util.Log;


import com.csweimei.rentmanagementtreasure.http.entity.AuthBean;
import com.csweimei.rentmanagementtreasure.http.entity.AutoBean;
import com.csweimei.rentmanagementtreasure.http.entity.BaseResult;
import com.csweimei.rentmanagementtreasure.http.entity.BindEntEntity;
import com.csweimei.rentmanagementtreasure.http.entity.BrokerCustomBean;
import com.csweimei.rentmanagementtreasure.http.entity.BrokerDailyBean;
import com.csweimei.rentmanagementtreasure.http.entity.BrokerFollowupBean;
import com.csweimei.rentmanagementtreasure.http.entity.BrokerHousingBean;
import com.csweimei.rentmanagementtreasure.http.entity.BrokerInfoBean;
import com.csweimei.rentmanagementtreasure.http.entity.CodeListBean;
import com.csweimei.rentmanagementtreasure.http.entity.CompanyBean;
import com.csweimei.rentmanagementtreasure.http.entity.CompanyInfoHomeBean;
import com.csweimei.rentmanagementtreasure.http.entity.CountBean;
import com.csweimei.rentmanagementtreasure.http.entity.CustomerBean;
import com.csweimei.rentmanagementtreasure.http.entity.CustomerCenterBean;
import com.csweimei.rentmanagementtreasure.http.entity.CustomerDetailBean;
import com.csweimei.rentmanagementtreasure.http.entity.CustomerFollowBean;
import com.csweimei.rentmanagementtreasure.http.entity.DailyListBean;
import com.csweimei.rentmanagementtreasure.http.entity.DealHouseListBean;
import com.csweimei.rentmanagementtreasure.http.entity.EntDealChatBean;
import com.csweimei.rentmanagementtreasure.http.entity.EntHomeDailyBean;
import com.csweimei.rentmanagementtreasure.http.entity.EntScheduleBean;
import com.csweimei.rentmanagementtreasure.http.entity.FollowListBean;
import com.csweimei.rentmanagementtreasure.http.entity.HouseDetailHzBean;
import com.csweimei.rentmanagementtreasure.http.entity.HouseDetailZzBean;
import com.csweimei.rentmanagementtreasure.http.entity.HouseFollowRecordBean;
import com.csweimei.rentmanagementtreasure.http.entity.HouseHistoryBean;
import com.csweimei.rentmanagementtreasure.http.entity.HouseInfoDetailBean;
import com.csweimei.rentmanagementtreasure.http.entity.HouseListBean;
import com.csweimei.rentmanagementtreasure.http.entity.HouseListEntBean;
import com.csweimei.rentmanagementtreasure.http.entity.JoinListBean;
import com.csweimei.rentmanagementtreasure.http.entity.LeaseDetailBean;
import com.csweimei.rentmanagementtreasure.http.entity.LeaseListBean;
import com.csweimei.rentmanagementtreasure.http.entity.LoginBean;
import com.csweimei.rentmanagementtreasure.http.entity.LookHouseBean;
import com.csweimei.rentmanagementtreasure.http.entity.MessageDetailBean;
import com.csweimei.rentmanagementtreasure.http.entity.MessageListBean;
import com.csweimei.rentmanagementtreasure.http.entity.NoticeMsgBean;
import com.csweimei.rentmanagementtreasure.http.entity.QuarterEntity;
import com.csweimei.rentmanagementtreasure.http.entity.SearchEntBean;
import com.csweimei.rentmanagementtreasure.http.entity.SearchStaffBean;
import com.csweimei.rentmanagementtreasure.http.entity.StaffListBean;
import com.csweimei.rentmanagementtreasure.http.entity.TabOne2Bean;
import com.csweimei.rentmanagementtreasure.http.entity.TabOneBean;
import com.csweimei.rentmanagementtreasure.http.entity.TabOneScheduleBean;
import com.csweimei.rentmanagementtreasure.http.entity.TabThreeBean;
import com.csweimei.rentmanagementtreasure.http.entity.TabTwoScheduleListBean;
import com.csweimei.rentmanagementtreasure.http.entity.UserInfoEntity;
import com.csweimei.rentmanagementtreasure.http.entity.VipBean;
import com.csweimei.rentmanagementtreasure.http.entity.WXBean;
import com.csweimei.rentmanagementtreasure.http.entity.WorkScheduleListBean;
import com.csweimei.rentmanagementtreasure.utils.uploadUtils.QiNiuYunBean;
import com.google.gson.Gson;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.TreeMap;

import io.reactivex.Observable;
import okhttp3.FormBody;
import okhttp3.RequestBody;

/**
 * Created by goldze on 2019/3/26.
 */
public class HttpDataSourceImpl implements HttpDataSource {
    private ApiService apiService;
    private volatile static HttpDataSourceImpl INSTANCE = null;

    public static HttpDataSourceImpl getInstance(ApiService apiService) {
        if (INSTANCE == null) {
            synchronized (HttpDataSourceImpl.class) {
                if (INSTANCE == null) {
                    INSTANCE = new HttpDataSourceImpl(apiService);
                }
            }
        }
        return INSTANCE;
    }

    public static void destroyInstance() {
        INSTANCE = null;
    }

    private HttpDataSourceImpl(ApiService apiService) {
        this.apiService = apiService;
    }


    private String key ="c4560666777kdjkdidcbe5f76d5bc4ff76b###888";
    private Map<String, String> resultMap;
    private MessageDigest alga;

    /**
     * map根据key值比较大小
     */
    private static Map<String, String> sortMapByKey(Map<String, String> map) {
        if (map == null || map.isEmpty()) {
            return null;
        }
        Map<String, String> sortMap = new TreeMap<>(String::compareTo);
        sortMap.putAll(map);
        return sortMap;
    }

    /**
     * 针对微信加密机制的问题，提供一个外部方法来解决
     */
    public void changeDigest() {
        if (alga != null) {
            alga.digest();
        }
    }

    /**
     * 数组转字符串
     *
     * @param b
     * @return
     */
    public static String byte2hex(byte[] b) {
        String hs = "";
        String stmp;
        for (int n = 0; n < b.length; n++) {
            stmp = (Integer.toHexString(b[n] & 0XFF));
            if (stmp.length() == 1) {
                hs = hs + "0" + stmp;
            } else {
                hs = hs + stmp;
            }
        }
        return hs;
    }

    /**
     * 内部处理Map集合
     * 得到from表单 (post请求)
     */
    private RequestBody getRequestBody(Map<String, String> map) {
        try {
            alga = MessageDigest.getInstance("SHA-1");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }


        RequestBody requestBody;
        FormBody.Builder builder = new FormBody.Builder();
        map.put("sign", null);
        resultMap = sortMapByKey(map);
        Log.e("LoggingI：", "map:" + resultMap.toString());
        Log.e("LoggingI：", "mapJson:" + new Gson().toJson(resultMap.toString()));
        String str = "";
        boolean isFirst = true;

        /**
         * 循环遍历获取key值，拼接sign字符串
         */
        for (Map.Entry<String, String> entry : resultMap.entrySet()) {
            if (entry.getValue() == null) {
                continue;
            }

            if (isFirst) {
                str += entry.getKey() + "=" + Base64.encodeToString(entry.getValue().getBytes(), Base64.DEFAULT).trim();
                isFirst = false;
            } else {
                str = str.trim();
                str += "&" + entry.getKey() + "=" + Base64.encodeToString(entry.getValue().getBytes(), Base64.DEFAULT).trim();
            }
        }
        str = str+"&" + "key" + "=" + key;
//        str = str.replace("+", "%2B");//去除+号
        str = str.replace("\n", "");//去除换行
        str = str.replace("\\s", "");//去除空格
        str = str.replace("&sign=", "");//去除空格
        changeDigest();
        alga.update(str.getBytes());
        Log.e("LoggingI：", "str:" + str);
        /**
         * 循环遍历value值，添加到表单
         */
        for (Map.Entry<String, String> entry : resultMap.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            if (value == null) {
                value = "";
            }
            if (key.equals("sign")) {
                value = byte2hex(alga.digest());
            } else if (key.equals("key")) {
                continue;
            }
            builder.add(key, value);
            Log.e("LoggingI：", "key:" + key + "--value:" + value);
        }
        requestBody = builder.build();
        return requestBody;
    }


    @Override
    public Observable<LoginBean> qq_login(Map<String, String> map) {
        return apiService.qq_login(getRequestBody(map));
    }

    @Override
    public Observable<LoginBean> wechet_login(Map<String, String> map) {
        return apiService.wechet_login(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> edituserinfo(Map<String, String> map) {
        return apiService.edituserinfo(getRequestBody(map));
    }

    @Override
    public Observable<UserInfoEntity> userinfo(Map<String, String> map) {
        return apiService.userinfo(getRequestBody(map));
    }

    @Override
    public Observable<AuthBean> seachauth(Map<String, String> map) {
        return apiService.seachauth(getRequestBody(map));
    }

    @Override
    public Observable<BindEntEntity> isbindEnt(Map<String, String> map) {
        return apiService.isbindEnt(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> logoff(Map<String, String> map) {
        return apiService.logoff(getRequestBody(map));
    }

    @Override
    public Observable<QuarterEntity> get_quarters(Map<String, String> map) {
        return apiService.get_quarters(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> add_quarters(Map<String, String> map) {
        return apiService.add_quarters(getRequestBody(map));
    }

    @Override
    public Observable<QiNiuYunBean> getToken() {
        return apiService.getToken();
    }

    @Override
    public Observable<BaseResult> addwhole(Map<String, String> map) {
        return apiService.addwhole(getRequestBody(map));
    }

    @Override
    public Observable<HouseInfoDetailBean> wholeinfo(Map<String, String> map) {
        return apiService.wholeinfo(getRequestBody(map));
    }

    @Override
    public Observable<HouseDetailHzBean> cotenancyinfo(Map<String, String> map) {
        return apiService.cotenancyinfo(getRequestBody(map));
    }

    @Override
    public Observable<HouseListBean> housinglist(Map<String, String> map) {
        return apiService.housinglist(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> housingstatic(Map<String, String> map) {
        return apiService.housingstatic(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> delete_housing(Map<String, String> map) {
        return apiService.delete_housing(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> edit_housing(Map<String, String> map) {
        return apiService.edit_housing(getRequestBody(map));
    }

    @Override
    public Observable<HouseFollowRecordBean> follow_housing(Map<String, String> map) {
        return apiService.follow_housing(getRequestBody(map));
    }

    @Override
    public Observable<CustomerFollowBean> followdetails(Map<String, String> map) {
        return apiService.followdetails(getRequestBody(map));
    }

    @Override
    public Observable<FollowListBean> followup(Map<String, String> map) {
        return apiService.followup(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> addfollow(Map<String, String> map) {
        return apiService.addfollow(getRequestBody(map));
    }

    @Override
    public Observable<LeaseListBean> leaselist(Map<String, String> map) {
        return apiService.leaselist(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> deletelease(Map<String, String> map) {
        return apiService.deletelease(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> addlease(Map<String, String> map) {
        return apiService.addlease(getRequestBody(map));
    }

    @Override
    public Observable<HouseHistoryBean> history_leaselist(Map<String, String> map) {
        return apiService.history_leaselist(getRequestBody(map));
    }

    @Override
    public Observable<LeaseDetailBean> lease_detail(Map<String, String> map) {
        return apiService.lease_detail(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> addcustom(Map<String, String> map) {
        return apiService.addcustom(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> deletecustom(Map<String, String> map) {
        return apiService.deletecustom(getRequestBody(map));
    }

    @Override
    public Observable<CustomerBean> seachcustom(Map<String, String> map) {
        return apiService.seachcustom(getRequestBody(map));
    }

    @Override
    public Observable<CustomerDetailBean> customdetails(Map<String, String> map) {
        return apiService.customdetails(getRequestBody(map));
    }

    @Override
    public Observable<LookHouseBean> showingslist(Map<String, String> map) {
        return apiService.showingslist(getRequestBody(map));
    }

    @Override
    public Observable<AutoBean> mateinfo(Map<String, String> map) {
        return apiService.mateinfo(getRequestBody(map));
    }

    @Override
    public Observable<HouseDetailZzBean> allhouser_data(Map<String, String> map) {
        return apiService.allhouser_data(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> addcotenancy(Map<String, String> map) {
        return apiService.addcotenancy(getRequestBody(map));
    }

    @Override
    public Observable<TabOneBean> beleaselist(Map<String, String> map) {
        return apiService.beleaselist(getRequestBody(map));
    }

    @Override
    public Observable<NoticeMsgBean> copywriting(Map<String, String> map) {
        return apiService.copywriting(getRequestBody(map));
    }

    @Override
    public Observable<TabOne2Bean> homerecords(Map<String, String> map) {
        return apiService.homerecords(getRequestBody(map));
    }

    @Override
    public Observable<TabOneScheduleBean> myschedule(Map<String, String> map) {
        return apiService.myschedule(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> addschedule(Map<String, String> map) {
        return apiService.addschedule(getRequestBody(map));
    }

    @Override
    public Observable<TabTwoScheduleListBean> schedulelist(Map<String, String> map) {
        return apiService.schedulelist(getRequestBody(map));
    }

    @Override
    public Observable<TabThreeBean> message_center(Map<String, String> map) {
        return apiService.message_center(getRequestBody(map));
    }

    @Override
    public Observable<MessageDetailBean> messageinfo(Map<String, String> map) {
        return apiService.messageinfo(getRequestBody(map));
    }

    @Override
    public Observable<MessageListBean> messagelist(Map<String, String> map) {
        return apiService.messagelist(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> edit_message(Map<String, String> map) {
        return apiService.edit_message(getRequestBody(map));
    }

    @Override
    public Observable<SearchEntBean> seachcompany(Map<String, String> map) {
        return apiService.seachcompany(getRequestBody(map));
    }

    @Override
    public Observable<DailyListBean> dailylist(Map<String, String> map) {
        return apiService.dailylist(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> adddaily(Map<String, String> map) {
        return apiService.adddaily(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> addbroker(Map<String, String> map) {
        return apiService.addbroker(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> dailydetails(Map<String, String> map) {
        return apiService.dailydetails(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> exit_company(Map<String, String> map) {
        return apiService.exit_company(getRequestBody(map));
    }

    @Override
    public Observable<CompanyBean> getcompany_info(Map<String, String> map) {
        return apiService.getcompany_info(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> companyinfo(Map<String, String> map) {
        return apiService.companyinfo(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> addcompanyauth(Map<String, String> map) {
        return apiService.addcompanyauth(getRequestBody(map));
    }

    @Override
    public Observable<EntDealChatBean> dealchat(Map<String, String> map) {
        return apiService.dealchat(getRequestBody(map));
    }

    @Override
    public Observable<EntHomeDailyBean> companydaily(Map<String, String> map) {
        return apiService.companydaily(getRequestBody(map));
    }

    @Override
    public Observable<EntScheduleBean> allschedule(Map<String, String> map) {
        return apiService.allschedule(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> companyseek(Map<String, String> map) {
        return apiService.companyseek(getRequestBody(map));
    }

    @Override
    public Observable<HouseListEntBean> allhousing(Map<String, String> map) {
        return apiService.allhousing(getRequestBody(map));
    }

    @Override
    public Observable<CustomerCenterBean> customcenter(Map<String, String> map) {
        return apiService.customcenter(getRequestBody(map));
    }

    @Override
    public Observable<DealHouseListBean> deallist(Map<String, String> map) {
        return apiService.deallist(getRequestBody(map));
    }

    @Override
    public Observable<WorkScheduleListBean> workschedule(Map<String, String> map) {
        return apiService.workschedule(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> handle(Map<String, String> map) {
        return apiService.handle(getRequestBody(map));
    }

    @Override
    public Observable<JoinListBean> joincompanylist(Map<String, String> map) {
        return apiService.joincompanylist(getRequestBody(map));
    }

    @Override
    public Observable<CompanyInfoHomeBean> myinfo(Map<String, String> map) {
        return apiService.myinfo(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> allhouser_data_ent(Map<String, String> map) {
        return apiService.allhouser_data_ent(getRequestBody(map));
    }

    @Override
    public Observable<StaffListBean> stafflist(Map<String, String> map) {
        return apiService.stafflist(getRequestBody(map));
    }

    @Override
    public Observable<BrokerFollowupBean> brokerfollowup(Map<String, String> map) {
        return apiService.brokerfollowup(getRequestBody(map));
    }

    @Override
    public Observable<BrokerDailyBean> brokerdaily(Map<String, String> map) {
        return apiService.brokerdaily(getRequestBody(map));
    }

    @Override
    public Observable<BrokerCustomBean> brokercustom(Map<String, String> map) {
        return apiService.brokercustom(getRequestBody(map));
    }

    @Override
    public Observable<BrokerInfoBean> brokeruser(Map<String, String> map) {
        return apiService.brokeruser(getRequestBody(map));
    }

    @Override
    public Observable<BrokerHousingBean> brokerhousingdata(Map<String, String> map) {
        return apiService.brokerhousingdata(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> deletebroker(Map<String, String> map) {
        return apiService.deletebroker(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> invitebroker(Map<String, String> map) {
        return apiService.invitebroker(getRequestBody(map));
    }

    @Override
    public Observable<SearchStaffBean> seachbroker(Map<String, String> map) {
        return apiService.seachbroker(getRequestBody(map));
    }

    @Override
    public Observable<VipBean> seach_vip(Map<String, String> map) {
        return apiService.seach_vip(getRequestBody(map));
    }

    @Override
    public Observable<CodeListBean> mycode(Map<String, String> map) {
        return apiService.mycode(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> usecode(Map<String, String> map) {
        return apiService.usecode(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> delete_code(Map<String, String> map) {
        return apiService.delete_code(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> deliver_code(Map<String, String> map) {
        return apiService.deliver_code(getRequestBody(map));
    }

    @Override
    public Observable<WXBean> WeChetPay(Map<String, String> map) {
        return apiService.WeChetPay(getRequestBody(map));
    }

    @Override
    public Observable<CountBean> housing_item(Map<String, String> map) {
        return apiService.housing_item(getRequestBody(map));
    }
}
